home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / CONTAINER / Container.C < prev    next >
C/C++ Source or Header  |  1992-06-22  |  5KB  |  257 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Container.h"
  6. #include "Class.h"
  7.  
  8. #include "Error.h"
  9. #include "String.h"
  10.  
  11. //---- initialization of exported variables -------------------------------------
  12.  
  13. char *cWarningActiveIterator= "there are active iterators";
  14. char *cWarningNullArgument  = "argument is a null pointer";
  15.  
  16. //---- Container -----------------------------------------------------------
  17.  
  18. NewAbstractMetaImpl0(Container,Object);
  19.  
  20. Container *Container::currentContainer;
  21.  
  22. Container::Container()
  23. {
  24.     size= 0;
  25.     nDeleted= 0;
  26.     iterCount= 0;
  27.     anchor.Init();
  28. }
  29.  
  30. Container::~Container()
  31. {
  32.     if ( HasIterator() )
  33.     ForIteratorsDoAndRemove(&Iterator::AboutToDie);     
  34. }
  35.  
  36. void Container::InitNew()
  37. {
  38.     size= 0;
  39.     nDeleted= 0;
  40.     iterCount= 0;
  41.     anchor.Init();
  42. }
  43.  
  44. int Container::Capacity()
  45. {
  46.     return size;
  47. }
  48.  
  49. bool Container::assertclass(Class *cl)
  50. {
  51.     register Object *op;
  52.     Iter next(this);
  53.     bool error= FALSE;
  54.  
  55.     if ( cl == 0 ) {
  56.     Error("assertclass", "class == 0");
  57.     return TRUE;
  58.     }
  59.     for ( int i= 0; op= next(); i++ )
  60.     if ( ! op->IsA()->isKindOf(cl) ) {
  61.         Error("assertclass", "element %d is not instance of class %s (%s)", i,
  62.                         cl->Name(), op->ClassName());
  63.         error= TRUE;
  64.     }
  65.     return error;
  66. }
  67.  
  68. void Container::InspectorId(char *b, int sz)
  69. {
  70.     static char cb[512];
  71.     Object *op= AnyElement();
  72.     
  73.     if (op) 
  74.     sprintf(cb, "[%d] <%s>", Size(), op->ClassName());
  75.     else
  76.     sprintf(cb, "[%d]", Size());
  77.     strn0cpy(b, cb, sz-1);   
  78. }
  79.  
  80. //---- container comparison
  81.  
  82. bool Container::IsEqual(Object *col)
  83. {   
  84.     // ?? this code is strange 
  85.     if ( IsA() != col->IsA() )
  86.     return FALSE;
  87.  
  88.     Iter next1(this), next2((Container *)col);
  89.     register Object *op1, *op2;
  90.  
  91.     for (;;) {
  92.     op1= next1();
  93.     op2= next2();
  94.     if ( op1 == 0 && op2 == 0 )
  95.         return TRUE;
  96.     if ( op1 == 0 || op2 == 0 ) 
  97.         break;
  98.     if ( ! op1->IsEqual(op2) )
  99.         break;
  100.     }
  101.     return FALSE;
  102. }
  103.  
  104. u_long Container::Hash()
  105. {
  106.     Iter next(this);
  107.     register Object *op;
  108.     register unsigned long s= 0;
  109.  
  110.     while ( op= next() )
  111.     s^= op->Hash();
  112.     return s;   
  113. }
  114.  
  115. //---- access 
  116.  
  117. Iterator *Container::MakeIterator(bool)
  118. {
  119.     AbstractMethod("MakeIterator");
  120.     return 0;
  121. }
  122.  
  123. Object *Container::AnyElement()
  124. {
  125.     Iter next(this);
  126.     return next();
  127. }
  128.  
  129. Object *Container::Find(Object *anOp)
  130. {
  131.     register Object *op;
  132.     
  133.     if ( anOp == 0 )
  134.     return 0;
  135.     Iter next(this);   
  136.     while ( op= next() )
  137.     if ( op->IsEqual(anOp) )
  138.         return op;
  139.     return 0;
  140. }
  141.  
  142. Object *Container::FindPtr(Object *anOp)
  143. {
  144.     register Object *op;
  145.     
  146.     if ( anOp == 0 )
  147.     return 0;
  148.     Iter next(this);   
  149.     while ( op= next() )
  150.     if ( op == anOp )
  151.         return op;
  152.     return 0;
  153. }
  154.  
  155. int Container::OccurrencesOf(Object *anOp)
  156. {
  157.     register Object *op;
  158.     register int n= 0;
  159.  
  160.     if ( anOp == 0 ) {
  161.     Warning("OccurrencesOf", cWarningNullArgument);
  162.     return 0;
  163.     }
  164.     Iter next(this);
  165.     while (op = next()) 
  166.     if ( op->IsEqual(anOp) )
  167.         n++;
  168.     return n;   
  169. }
  170.  
  171. int Container::OccurrencesOfPtr(Object *anOp)
  172. {
  173.     register Object *op;
  174.     register int n= 0;
  175.  
  176.     if ( anOp == 0 )
  177.     return FALSE;
  178.     Iter next(this);
  179.     while ( op= next() ) 
  180.     if ( op == anOp )
  181.         n++;
  182.     return n;   
  183. }
  184.  
  185. //---- object i/o
  186.  
  187. OStream &Container::PrintOn(OStream &os)
  188. {
  189.     Object::PrintOn(os);
  190.     os << size SP;
  191.     return os;
  192. }
  193.  
  194. IStream &Container::ReadFrom(IStream &is)
  195. {
  196.     Object::ReadFrom(is);
  197.     is >> size;
  198.     anchor.Init();
  199.     return is;
  200. }
  201.  
  202. //---- robust iterators 
  203.  
  204. void Container::IteratorStart(Iterator *it)
  205. {
  206.     if ( it ) {
  207.     iterCount++;
  208.     it->ChainIn(&anchor);
  209.     } else 
  210.     Warning("IteratorStarts", cWarningNullArgument);
  211. }
  212.  
  213. void Container::IteratorTerminate(Iterator *it)
  214. {
  215.     if ( it ) {
  216.     iterCount--;
  217.     it->ChainOut();
  218.     if ( iterCount < 0 )
  219.         Error("IteratorTerminate", "iterCount < 0");
  220.     if ( HasDeletedObjects() && iterCount <= 0 )
  221.         RemoveDeleted();
  222.     } else
  223.     Warning("IteratorTerminate", cWarningNullArgument);
  224.  
  225. void Container::ForIteratorsDoAndRemove(IteratorMethod method, void *arg)
  226. {
  227.     register Iterator *it, *jt;
  228.     
  229.     it= anchor.next;
  230.     while ( it != &anchor ) {
  231.     jt= it;
  232.     it= it->next;
  233.     (jt->*method)(arg);
  234.     jt->ChainOut();
  235.     }
  236. }
  237.  
  238. void Container::ForIteratorsDo(IteratorMethod method, void *arg)
  239. {
  240.     register Iterator *it;
  241.     
  242.     it= anchor.next;
  243.     while ( it != &anchor ) {
  244.     (it->*method)(arg);
  245.     it= it->next;
  246.     }
  247. }
  248.  
  249. //---- robust iterators - Deleted Object approach (old style) ----
  250.  
  251. void Container::RemoveDeleted()
  252. {
  253.     // hook
  254. }
  255.  
  256.